home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1997 September / Macworld (1997-09).dmg / Shareware World / Utilities / Text Processing / Alpha / Tcl / SystemCode / diff.tcl < prev    next >
Text File  |  1996-08-15  |  8KB  |  299 lines

  1.  
  2. # Usage: diff [-#] [-abBcdefhHilnNprstTuvw] [-C lines] [-F regexp] [-I regexp]
  3. #        [-L label [-L label]] [-S file] [-D symbol] [+ignore-blank-lines]
  4. #        [+context[=lines]] [+unified[=lines]] [+ifdef=symbol]
  5. #        [+show-function-line=regexp]
  6. #        [+speed-large-files] [+ignore-matching-lines=regexp] [+new-file]
  7. #        [+initial-tab] [+starting-file=file] [+text] [+all-text] [+ascii]
  8. #        [+minimal] [+ignore-space-change] [+ed] [+reversed-ed] [+ignore-case]
  9. #        [+print] [+rcs] [+show-c-function] [+binary] [+brief] [+recursive]
  10. #        [+report-identical-files] [+expand-tabs] [+ignore-all-space]
  11. #        [+file-label=label [+file-label=label]] [+version] path1 path2
  12.  
  13.  
  14. proc compareDirectories {} {
  15.     global diffOne diffTwo
  16.     
  17. #    return "Closed for repairs…"
  18.  
  19.     set diffOne [string trimright [get_directory -p "Select dir 1:"] {:}]
  20.     set diffTwo [string trimright [get_directory -p "Select dir 2:"] {:}]
  21.  
  22.     doTheCompare 1 {* Directory Comparison *}
  23. }
  24.  
  25.  
  26. proc compareFiles {} {
  27.     global tileWidth tileHeight tileTop tileLeft
  28.     global diffOne diffTwo
  29.  
  30.     set diffOne [getfile "Select your first file:"]
  31.     set diffTwo [getfile "Select your second file:"]
  32.     
  33.     if {[lsearch [winNames -f] $diffOne] >= 0} {
  34.         bringToFront $diffOne
  35.         killWindow
  36.         if {[lsearch [winNames -f] $diffOne] >= 0} {return}
  37.     }
  38.     if {[lsearch [winNames -f] $diffTwo] >= 0} {
  39.         bringToFront $diffTwo
  40.         killWindow
  41.         if {[lsearch [winNames -f] $diffTwo] >= 0} {return}
  42.     }
  43.     
  44.     set geo1 [diffGeo 1]
  45.     set geo2 [diffGeo 0]
  46.     
  47.     edit -g [lindex $geo1 0] [lindex $geo1 1] [lindex $geo1 2] [lindex $geo1 3] $diffOne
  48.     set diffOne [car [winNames -f]]
  49.     display 0
  50.     goto 0
  51.  
  52.     edit -g [lindex $geo2 0] [lindex $geo2 1] [lindex $geo2 2] [lindex $geo2 3] $diffTwo
  53.     set diffTwo [car [winNames -f]]
  54.     display 0
  55.     goto 0
  56.     
  57.     doTheCompare
  58. }
  59.  
  60. proc diffGeo {left} {
  61.     global tileWidth tileHeight tileTop tileLeft
  62.  
  63.     set margin 4
  64.     set width [expr ($tileWidth - $margin)/2]
  65.     set height [expr $tileHeight - 200]
  66.     set hor $tileLeft
  67.  
  68.     if {!$left} {incr hor [expr $width+$margin]}
  69.     
  70.     return [list $hor $tileTop $width $height]
  71. }
  72.  
  73.  
  74. proc compareWindows {} {
  75.     global tileHeight tileWidth tileTop tileLeft
  76.     global diffOne diffTwo
  77.  
  78.     set wins [winNames -f]
  79.     if {[llength $wins] < 2} { message "Need 2 windows"; return }
  80.     
  81.     set diffOne [lindex $wins 0]
  82.     set diffTwo [lindex $wins 1]
  83.     
  84.     for {set i 0} {$i < 2} {incr i} {
  85.         set nm [lindex $wins $i]
  86.         getWinInfo -w $nm b
  87.         if {$b(dirty) == 1} {
  88.             alertnote "Can't compare because the window $nm has unsaved changes. \
  89. Save it and try again."
  90.             return
  91.         }
  92.     }
  93.  
  94.     set geo0 [diffGeo 1]
  95.     set geo1 [diffGeo 0]
  96.     
  97.     for {set i 0} {$i < 2} {incr i} {
  98.         moveWin [lindex $wins $i] 1000 0
  99.         sizeWin [lindex $wins $i] [lindex [set geo$i] 2] [lindex [set geo$i] 3]
  100.     }
  101.  
  102.     for {set i 0} {$i < 2} {incr i} {
  103.         moveWin [lindex $wins $i] [lindex [set geo$i] 0]  [lindex [set geo$i] 1]
  104.     }
  105.  
  106.     doTheCompare
  107. }
  108.  
  109. proc trimnum {str} {
  110.     if {[regexp -indices { <[0-9]+>$} $str ind]} {
  111.         return [string range $str 0 [expr [lindex $ind 0] - 1]]
  112.     } else {
  113.         return $str
  114.     }
  115. }
  116. # proc trimB {wname} {regsub { <[0-9]*>$} $wname "" wname;return $wname}
  117.  
  118.  
  119. proc doTheCompare {{isdir 0} {name {* File Comparison *}}} {
  120.     global tileLeft tileTop tileWidth tileHeight diffFlags
  121.     global diffOne diffTwo winModes HOME diffDir
  122.     
  123.     set diffDir $isdir
  124.  
  125.     message "Launching 'GNU Diff'"
  126.     launch "$HOME:Tools:GNU Diff"
  127.     message "Starting diff…"
  128.     set dtext [dosc -n "GNU Diff" -s "$diffFlags \"[trimnum $diffOne]\" \"[trimnum $diffTwo]\""]
  129.     message "Starting diff…done"
  130.     
  131.  
  132.     if {![string length $dtext]} {
  133.         alertnote    "No difference:\r$diffOne\r$diffTwo"
  134.         return
  135.     }    
  136.     set top [expr $tileTop + $tileHeight - 178]
  137.     new -n $name -g $tileLeft $top [expr $tileWidth - 6] 178
  138.     changeMode [set winModes([lindex [winNames] 0]) Diff]
  139.     insertText "\r$dtext\r"
  140.     goto 0
  141.     setWinInfo dirty 0
  142.     setWinInfo read-only 1
  143.     select 0 [nextLineStart 0]
  144. }
  145.  
  146.  
  147. proc upDiff {} {
  148.     set limit 0
  149.     set res [search -s -f 0 -r 1 {^[^- \r]+\r} [expr [getPos] - 1]]
  150.     set pos [lindex $res 0]
  151.     select $pos [nextLineStart $pos]
  152.     
  153. }
  154. #     set res [search -s -f 0 -r 1 {^[^-<>]} [expr [getPos] - 1]]
  155.  
  156. proc downDiff {} {
  157.     set limit 0
  158.     set res [search -s -f 1 -r 1 {^[^- \r]+\r} [expr [getPos] + 1]]
  159.     set pos [lindex $res 0]
  160.     display $pos
  161.     select $pos [nextLineStart $pos]
  162.     
  163. }
  164. #     set res [search -s -f 1 -r 1 {^[^-<>]} [expr [getPos] + 1]]
  165.  
  166. #           n1 a n3,n4
  167. #           n1,n2 d n3
  168. #           n1,n2 c n3,n4
  169.  
  170. proc selectDiff {} {
  171.     global diffOne diffTwo diffDir
  172.     
  173.     set text [getText [lineStart [getPos]] [expr [nextLineStart [getPos]] - 1]]
  174.     
  175.     if {![regexp {[acd]} $text char]} return
  176.     set res [split $text $char]
  177.     if {![scan [lindex $res 0] "%d" one]} return
  178.     if {![scan [lindex $res 1] "%d" two]} return
  179.     if {$one == 1} {incr one}
  180.     if {$two == 1} {incr two}
  181.  
  182.     if {$diffDir} {
  183.         set res [search -s -f 0 -r 1 "^diff.*\r" [getPos]]
  184.         set text [eval getText $res]
  185.         set len [llength $text]
  186.         set diffOne [lindex $text [expr $len - 2]]
  187.         set diffTwo [lindex $text [expr $len - 1]]
  188.     }
  189.     diffDisplay $diffOne [expr $one - 1] 1
  190.     diffDisplay $diffTwo [expr $two - 1] 0
  191.  
  192.     if {$diffDir} {
  193.         if {![string match {* Directory Comparison *} [car [winNames -f]]]} {
  194.             catch {bringToFront "* Directory Comparison *"}
  195.         }
  196.     }
  197. }
  198.  
  199. proc diffDisplay {wname row left} {
  200.     global diffDir
  201.  
  202.     if {$diffDir} {
  203.         set geo [diffGeo $left]
  204.         if {[set res [lsearch [winNames -f] "$wname*"]] < 0} {
  205.             eval edit -g $geo [list $wname]
  206.             set wname [car [winNames -f]]
  207.         } else {
  208.             set wname [lindex [winNames -f] $res]
  209.             if {[getGeometry $wname] != $geo} {
  210.                 sizeWin $wname [lindex $geo 2] [lindex $geo 3]
  211.                 moveWin $wname [lindex $geo 0] [lindex $geo 1]
  212.             }
  213.             if {$res > 2} {
  214.                 bringToFront $wname
  215.             }
  216.         }
  217.     }
  218.  
  219.     display -w $wname [rowColToPos -w $wname $row 0]
  220. }
  221.  
  222. proc diffSel {wname ro row rowd left} {
  223.     global diffDir
  224.  
  225.     if {$diffDir} {
  226.         set geo [diffGeo $left]
  227.         if {[set res [lsearch [winNames -f] "$wname*"]] < 0} {
  228.             eval edit -g $geo [list $wname]
  229.             set wname [car [winNames -f]]
  230.         } else {
  231.             set wname [lindex [winNames -f] $res]
  232.             if {[getGeometry $wname] != $geo} {
  233.                 sizeWin $wname [lindex $geo 2] [lindex $geo 3]
  234.                 moveWin $wname [lindex $geo 0] [lindex $geo 1]
  235.             }
  236.         }
  237.     }
  238.     bringToFront $wname
  239.  
  240.     display [rowColToPos $ro 0]
  241.     select [rowColToPos $row 0] [rowColToPos [expr $rowd + 1] 0]
  242. }
  243. #     goto [rowColToPos $row 0]
  244.  
  245. proc viewDiff {} {
  246.     global diffOne diffTwo diffDir
  247.     
  248.     set text [getText [lineStart [getPos]] [expr [nextLineStart [getPos]] - 1]]
  249.     
  250.     if {![regexp {[acd]} $text char]} return
  251.     set res [split $text $char]
  252.     if {![scan [lindex $res 0] "%d,%d" one oned]} return
  253.     if {![scan [lindex $res 1] "%d,%d" two twod]} return
  254.     set on $one
  255.     set tw $two
  256.     if {$on == 1} {incr on}
  257.     if {$tw == 1} {incr tw}
  258.     if {![info exists oned]} {set oned $one}
  259.     if {![info exists twod]} {set twod $two}
  260.  
  261.     if {$diffDir} {
  262.         set res [search -s -f 0 -r 1 "^diff.*\r" [getPos]]
  263.         set text [eval getText $res]
  264.         set diffOne [lindex $text 1]
  265.         set diffTwo [lindex $text 2]
  266.     }
  267.     diffSel $diffOne [expr $on - 1] $one $oned 1
  268.     diffSel $diffTwo [expr $tw - 1] $two $twod 0
  269.     if {$diffDir} {
  270.         catch {bringToFront "* Directory Comparison *"}
  271.     } else {
  272.         catch {bringToFront "* File Comparison *"}
  273.     }
  274. }
  275.  
  276. proc diffWin {} {
  277.     global winModes
  278.     set files [winNames -f]
  279.     set len [llength $files]
  280.         for {set i 0} {$i < $len} {incr i} {
  281.             if {$winModes([lindex [winNames -f] $i]) == "Diff"} {
  282.                 bringToFront [lindex [winNames] $i]
  283.                 return
  284.             }
  285.         }
  286.     beep
  287.     message "No Diff window."
  288. }
  289.  
  290. bind '\r'        selectDiff    Diff
  291. bind '\t'        viewDiff    Diff
  292. bind Kpad. <c>        diffWin
  293. bind Enter        {downDiff;selectDiff}    Diff
  294. bind Kpad0        {upDiff;selectDiff}    Diff
  295. bind down         downDiff Diff
  296. bind up         upDiff Diff
  297.  
  298.  
  299.